﻿using System;
using System.Collections.Generic;
 
using System.Text;
using System.Runtime.InteropServices;


namespace HDF5
{
    using hid_t = System.Int32;
    using herr_t = System.Int32;
    using hsize_t = System.UInt64;
    using hssize_t = System.Int64;
    using hunsigned = System.UInt32;

    using hbool_t = System.UInt32;
    using htri_t = System.Int32;
    using ssize_t = System.Int64;

    using haddr_t = System.UInt64;

    using uint32_t = System.UInt32;
    using uint64_t = System.UInt64;

    using H5O_msg_crt_idx_t = System.UInt32;

    using size_t = System.UInt32;

    using off_t = System.Int32;

    using H5E_major_t = System.Int32;
    using H5E_minor_t = System.Int32;

    using time_t = System.Int64;
    using H5Z_filter_t = System.Int32;

    #region delegates
    /* The H5L_class_t struct can be used to override the behavior of a
     * "user-defined" link class. Users should populate the struct with callback
     * functions defined below.
     */
    /* Callback prototypes for user-defined links */
    /* Link creation callback */
    public delegate herr_t H5L_create_func_t([In][MarshalAs(UnmanagedType.LPStr)] string link_name, hid_t loc_group,IntPtr lnkdata, size_t lnkdata_size, hid_t lcpl_id);

    /* Callback for when the link is moved */
    public delegate herr_t H5L_move_func_t([In][MarshalAs(UnmanagedType.LPStr)] string new_name, hid_t new_loc,IntPtr lnkdata, size_t lnkdata_size);

    /* Callback for when the link is copied */
    public delegate herr_t H5L_copy_func_t([In][MarshalAs(UnmanagedType.LPStr)] string new_name, hid_t new_loc, IntPtr lnkdata, size_t lnkdata_size);

    /* Callback during link traversal */
    public delegate herr_t H5L_traverse_func_t([In][MarshalAs(UnmanagedType.LPStr)] string link_name, hid_t cur_group,IntPtr lnkdata, size_t lnkdata_size, hid_t lapl_id);

    /* Callback for when the link is deleted */
    public delegate herr_t H5L_delete_func_t([In][MarshalAs(UnmanagedType.LPStr)] string link_name, hid_t file, IntPtr lnkdata, size_t lnkdata_size);

    /* Callback for querying the link */
    /* Returns the size of the buffer needed */
    public delegate ssize_t H5L_query_func_t([In][MarshalAs(UnmanagedType.LPStr)] string link_name, IntPtr lnkdata, size_t lnkdata_size, IntPtr buf, size_t buf_size);

    /* Callback for external link traversal */
    public delegate herr_t H5L_elink_traverse_t([In][MarshalAs(UnmanagedType.LPStr)] string parent_file_name,
    [In][MarshalAs(UnmanagedType.LPStr)] string parent_group_name, [In][MarshalAs(UnmanagedType.LPStr)] string child_file_name,
    [In][MarshalAs(UnmanagedType.LPStr)] string child_object_name, ref hunsigned acc_flags, hid_t fapl_id, IntPtr op_data);


    #endregion delegates

    #region enums

    /* Link class types.
     * Values less than 64 are reserved for the HDF5 library's internal use.
     * Values 64 to 255 are for "user-defined" link class types; these types are
     * defined by HDF5 but their behavior can be overridden by users.
     * Users who want to create new classes of links should contact the HDF5
     * development team at hdfhelp@ncsa.uiuc.edu .
     * These values can never change because they appear in HDF5 files.
     */
    public enum H5L_type_t {
        H5L_TYPE_ERROR = (-1),      /* Invalid link type id         */
        H5L_TYPE_HARD = 0,          /* Hard link id                 */
        H5L_TYPE_SOFT = 1,          /* Soft link id                 */
        H5L_TYPE_EXTERNAL = 64,     /* External link id             */
        H5L_TYPE_MAX = 255	        /* Maximum link type id         */
    }

    #endregion enums


    #region structs
    /* Information struct for link (for H5Lget_info/H5Lget_info_by_idx) */
    public struct H5L_info_t {
        H5L_type_t          type;           /* Type of link                   */
        hbool_t             corder_valid;   /* Indicate if creation order is valid */
        System.Int64             corder;         /* Creation order                 */
        H5T_cset_t          cset;           /* Character set of link name     */
        //union
         haddr_t         address;        /* Address hard link points to    */
        //    size_t          val_size;       /* Size of a soft link or UD link value */
        
    } 

    ///* User-defined link types */
    //public struct {
    //    int version;                    /* Version number of this struct        */
    //    H5L_type_t id;                  /* Link type ID                         */
    //    const char *comment;            /* Comment for debugging                */
    //    H5L_create_func_t create_func;  /* Callback during link creation        */
    //    H5L_move_func_t move_func;      /* Callback after moving link           */
    //    H5L_copy_func_t copy_func;      /* Callback after copying link          */
    //    H5L_traverse_func_t trav_func;  /* Callback during link traversal       */
    //    H5L_delete_func_t del_func;     /* Callback for link deletion           */
    //    H5L_query_func_t query_func;    /* Callback for queries                 */
    //} H5L_class_t;
    #endregion structs

    /* Prototype for H5Literate/H5Literate_by_name() operator */
    public delegate herr_t H5L_iterate_t(hid_t group, [In][MarshalAs(UnmanagedType.LPStr)] string name, ref H5L_info_t info, IntPtr op_data);

    public static class H5L
    {
        /* Maximum length of a link's name */
        /* (encoded in a 32-bit unsigned integer) */
        public static UInt32 H5L_MAX_LINK_NAME_LEN = unchecked((UInt32)(-1)); /* (4GB - 1) */


            /* Macro to indicate operation occurs on same location */
        public static hid_t H5L_SAME_LOC =0;

        /* Current version of the H5L_class_t struct */
        public static hid_t H5L_LINK_CLASS_T_VERS= 0;


        #region Links Functions
        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Lcreate_hard( hid_t obj_loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string obj_name, hid_t link_loc_id,[In][MarshalAs(UnmanagedType.LPStr)] string link_name, hid_t lcpl_id, hid_t lapl_id )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Lcreate_soft( [In][MarshalAs(UnmanagedType.LPStr)] string target_path, hid_t link_loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string link_name, hid_t lcpl_id, hid_t lapl_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Lcreate_external( [In][MarshalAs(UnmanagedType.LPStr)] string file_name, [In][MarshalAs(UnmanagedType.LPStr)] string object_name, hid_t link_loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string link_name, hid_t lcpl_id, hid_t lapl_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern htri_t H5Lexists( hid_t loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string name, hid_t lapl_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Lmove( hid_t src_loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string src_name, hid_t dest_loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string dest_name, hid_t lcpl, hid_t lapl ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Lcopy( hid_t src_loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string src_name, hid_t dest_loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string dest_name, hid_t lcpl_id, hid_t lapl_id )  ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Ldelete( hid_t loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string name, hid_t lapl_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Lget_info( hid_t link_loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string link_name, ref H5L_info_t link_buff, hid_t lapl_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Lget_val( hid_t link_loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string link_name, IntPtr linkval_buff, size_t size, hid_t lapl_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Lunpack_elink_val( StringBuilder ext_linkval, size_t link_size, out hunsigned flags, IntPtr[] filename, IntPtr[] obj_path ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Lcreate_ud( hid_t link_loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string link_name, H5L_type_t link_type, [In][MarshalAs(UnmanagedType.LPStr)] string udata, size_t udata_size, hid_t lcpl_id, hid_t lapl_id )  ;

        //[DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        //public static extern herr_t H5Lregister( const H5L_class_t * link_class ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Lunregister( H5L_type_t link_cls_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern htri_t H5Lis_registered( H5L_type_t link_cls_id ) ;

        //[DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        //public static extern herr_t H5Literate( hid_t group_id, H5_index_t index_type, H5_iter_order_t order, hsize_t *idx, H5L_iterate_t op, void *op_data ) ;

        //[DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        //public static extern herr_t H5Literate_by_name( hid_t loc_id, const char *group_name, H5_index_t index_type, H5_iter_order_t order, hsize_t *idx, H5L_iterate_t op, void *op_data, hid_t *lapl_id ) ;

        //[DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        //public static extern herr_t H5Lvisit( hid_t group_id, H5_index_t index_type, H5_iter_order_t order, H5L_iterate_t op, void *op_data ) ;

        //[DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        //public static extern herr_t H5Lvisit_by_name( hid_t loc_id, const char *group_name, H5_index_t index_type, H5_iter_order_t order, H5L_iterate_t op, void *op_data, hid_t lapl_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Lget_info_by_idx( hid_t loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string group_name, H5_index_t index_field, H5_iter_order_t order, hsize_t n, ref H5L_info_t link_val, hid_t lapl_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern ssize_t H5Lget_name_by_idx( hid_t loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string group_name, H5_index_t index_field, H5_iter_order_t order, hsize_t n, StringBuilder name, size_t size, hid_t lapl_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Lget_val_by_idx( hid_t loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string group_name, H5_index_t index_type, H5_iter_order_t order, hsize_t n, IntPtr link_val, size_t size, hid_t lapl_id ) ;

        [DllImport("hdf5dll.dll",CharSet=CharSet.Ansi)]
        public static extern herr_t H5Ldelete_by_idx( hid_t loc_id, [In][MarshalAs(UnmanagedType.LPStr)] string group_name, H5_index_t index_field, H5_iter_order_t order, hsize_t n, hid_t lapl_id );



        #endregion Links Functions





    }
}
